#include "TcpServer.h"

TcpServer::TcpServer(const std::string &ip, const uint16_t port, int threadNum): threadNum_(threadNum)
{
    // 创建主事件循环
    mainLoop_ = new EventLoop();
    mainLoop_->setepolltimeoutcallback(std::bind(&TcpServer::epolltimeout, this, std::placeholders::_1));

    // 创建服务端连接对象
    acceptor_ = new Acceptor(mainLoop_, ip, port);
    acceptor_->setnewconnectioncb(std::bind(&TcpServer::newconnection, this, std::placeholders::_1));

    // 创建线程池
    threadPoll_ = new ThreadPoll(threadNum_, "IO");
    // 创建从事件循环
    for(int i = 0; i < threadNum_; i++)
    {
        // 将从事件循环添加到 subLoops 容器中
        subLoops_.push_back(new EventLoop);
        subLoops_[i]->setepolltimeoutcallback(std::bind(&TcpServer::epolltimeout, this, std::placeholders::_1));
        // 启动从事件循环，并添加到线程池中运行
        threadPoll_->AddTask(std::bind(&EventLoop::run, subLoops_[i]));
    }
}

TcpServer::~TcpServer()
{
    delete acceptor_;
    delete mainLoop_;
    // 释放从事件循环
    for(auto &aa: subLoops_)
    {
        delete aa;
    }
    // 释放线程池
    delete threadPoll_;
}

void TcpServer::start()
{
    mainLoop_->run();
}

void TcpServer::newconnection(Socket *clientsock)
{
    // 连接上来的客户端采用边缘事件的读事件
    std::shared_ptr<Connection>conn(new Connection(subLoops_[clientsock->fd() % threadNum_], clientsock));
    conn->setclosecallback(std::bind(&TcpServer::closeconnection, this, std::placeholders::_1));
    conn->seterrorcallback(std::bind(&TcpServer::errorconnection, this, std::placeholders::_1));
    conn->setonmessagecallback(std::bind(&TcpServer::message, this, std::placeholders::_1, std::placeholders::_2));
    conn->setsendcompletecallback(std::bind(&TcpServer::sendcomplete, this, std::placeholders::_1));
    
    // printf ("accept client(socketfd=%d, ip=%s,port=%d) ok.\n", clientsock->fd(), clientsock->ip().c_str(), clientsock->port());
    // 把conn存放到map容器中
    conns_[conn->fd()] = conn;   

    if(newconnectioncallback_)
    {
        newconnectioncallback_(conn);
    }
}

void TcpServer::closeconnection(std::shared_ptr<Connection>conn)
{
    if(closeconnectioncallback_)
    {
        closeconnectioncallback_(conn);
    }
    
    // printf("client(eventfd=%d) disconnected.\n", conn->fd());
    // 从map中删除连接
    conns_.erase(conn->fd());
}

void TcpServer::errorconnection(std::shared_ptr<Connection>conn)
{
    if(errorconnectioncallback_)
    {
        errorconnectioncallback_(conn);
    }

    // printf("client(eventfd=%d) error.\n", conn->fd());
    // 从map中删除连接
    conns_.erase(conn->fd());
}

void TcpServer::message(std::shared_ptr<Connection>conn, std::string& message)
{
    /*
    // printf("message (eventfd=%d):%s\n", fd(), message.c_str());
    // ...假设这里对接收到的报文数据做了许多逻辑处理
    message = "reply:" + message;
    // 将数据添加到发生缓冲区中，待监听到写事件时回调时发送
    conn->send(message.data(), message.size());
    */

     if(onmessagecallback_)
     {
        onmessagecallback_(conn, message);
     }
}

void TcpServer::sendcomplete(std::shared_ptr<Connection>conn)
{
    // printf("send complete \n");
    
    if(sendcompletecallback_)
    {
        sendcompletecallback_(conn);
    }
}

void TcpServer::epolltimeout(EventLoop *loop)
{
    // printf("epoll_wait() timeout \n");
    
    if(epolltimeoutcallback_)
    {
        epolltimeoutcallback_(loop);
    }
}

void TcpServer::setnewconnectioncallback(std::function<void(std::shared_ptr<Connection>)> fn)
{
    newconnectioncallback_ = fn;
}

void TcpServer::setcloseconnectioncallback(std::function<void(std::shared_ptr<Connection>)> fn)
{
    closeconnectioncallback_ = fn;
}

void TcpServer::seterrorconnectioncallback(std::function<void(std::shared_ptr<Connection>)> fn)
{
    errorconnectioncallback_ = fn;
}

void TcpServer::setonmessagecallback(std::function<void(std::shared_ptr<Connection>, std::string&)> fn)
{
    onmessagecallback_ = fn;
}

void TcpServer::setsendcompletecallback(std::function<void(std::shared_ptr<Connection>)> fn)
{
    sendcompletecallback_ = fn;
}

void TcpServer::setepolltimeoutcallback(std::function<void(EventLoop*)> fn)
{
    epolltimeoutcallback_ = fn;
}
